package JavaN.Java8;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.Optional;

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
class OptionalUser {
    private User user;

}

/**
 * Optional类：为了在程序中避免出现空指针异常而创建的。
 *
 * 常用的方法：ofNullable(T t)
 *            orElse(T t)
 * ●Optional提供很 多有用的方法，这样我们就不用显式进行空值检测。
 * ●创建Optional类对象的方法:
 * ➢Optional.of(T t):创建一个Optional实例，t必须非空;
 * ➢Optional.empty() :创建一个空的Optional 实例
 * ➢Optional.ofNullable(T t): t可以为null
 * ●判断Optional容器中是否包含对象:
 * ➢boolean isPresent() :判断是否包含对象
 * ➢void ifPresent(Consumer<? super T> consumer) :如果有值，就执行Consumer
 * 接口的实现代码，并且该值会作为参数传给它。
 * ●获取Optional容器的对象:
 * ➢T get():如果调用对象包含值，返回该值，否则抛异常
 * ➢T orElse(T other) :如果有值则将其返回，否则返回指定的other对象。
 * ➢T orElseGet(Supplier<? extends T> other) :如果有值则将其返回，否则返回由
 * Supplier接口实现提供的对象。
 * ➢T orElse Throw(Supplier<? extends X> exceptionSupplier):如果有值则将其返
 * 回，否则抛出由Supplier接口实现提供的异常。
 * 让天下没有难学的技成
 */
public class Optional避免空指针 {
    public static void main(String[] args) {

        OptionalUser optionalUser = new OptionalUser();
        optionalUser.setUser(new User(1, "张蛟龙", 34));
//        Optional<User> user = Optional.of(optionalUser.getUser());//会引发空指针异常
        Optional<User> user = Optional.ofNullable(optionalUser.getUser());//空的话 Optional.empty
        System.out.println(user);

        //orElse  如果当前user为空 则返回orElse传入的User   如果user非空，返回内部的User
        User user1 = user.orElse(new User(1001, "马化腾", 34));
        System.out.println(user1);
        System.out.println("*********getUsername方法*******************************");
        OptionalUser o1 = null;
        String userName0 = getUserName(o1);
        System.out.println("全空"+userName0);
        o1 = new OptionalUser();
        String userName1 = getUserName(o1);
        System.out.println("半空"+userName1);
        o1 = new OptionalUser(new User(3, "apc", 20));
        String userName2 = getUserName(o1);
        System.out.println("实心"+userName2);

    }
    private static String getUserName(OptionalUser o){
        //orElse  如果当前user为空 则返回orElse传入的User   如果user非空，返回内部的User
        Optional<OptionalUser> o1 = Optional.ofNullable(o);
        OptionalUser o2 = o1.orElse(new OptionalUser(new User(1, "张蛟龙", 22)));
        Optional<User> user = Optional.ofNullable(o2.getUser());
        User user1 = user.orElse(new User(2, "毛纪", 21));
        return user1.getUsername();
    }
}
